package xyz.xmh.template;

import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import reactor.core.publisher.Mono;
import xyz.xmh.cache.Cache;
import xyz.xmh.cache.NullCache;
import xyz.xmh.dao.file.ReactiveFileDao;
import xyz.xmh.dao.recycle.ReactiveRecycleDao;
import xyz.xmh.executor.ReactiveBaseExecutor;
import xyz.xmh.executor.ReactiveCacheExecutor;
import xyz.xmh.executor.ReactiveExecutor;
import xyz.xmh.pojo.entity.BaseItem;
import xyz.xmh.pojo.enums.CategoryEnum;
import xyz.xmh.pojo.enums.CheckNameEnum;
import xyz.xmh.pojo.request.file.ListRequest;
import xyz.xmh.pojo.request.file.SearchRequest;
import xyz.xmh.pojo.request.file.UpdateRequest;
import xyz.xmh.pojo.response.file.*;

import java.nio.file.Path;

/**
 * 2021/10/26 14:56 星期二<br/>
 * 反应式的客户端模板，适用于直接返回http实体
 *
 * @author xuMingHai
 */
public class ReactiveClientTemplate implements ReactiveExecutor {

    /**
     * 响应式客户端
     */
    private final ReactiveExecutor reactiveExecutor;

    /**
     * 缓存实例
     */
    private final Cache cache;

    public ReactiveClientTemplate(Cache cache, ReactiveFileDao reactiveFileDao, ReactiveRecycleDao reactiveRecycleDao) {
        final ReactiveBaseExecutor reactiveBaseExecutor = new ReactiveBaseExecutor(reactiveFileDao, reactiveRecycleDao);
        this.cache = cache;

        if (NullCache.NULL_CACHE.equals(cache.getName())) {
            this.reactiveExecutor = reactiveBaseExecutor;
        } else {
            this.reactiveExecutor = new ReactiveCacheExecutor(cache, reactiveBaseExecutor);
        }
    }

    /**
     * 获取缓存实例
     *
     * @return 缓存实例，如果没有开启缓存会返回空对象缓存
     */
    public Cache getCache() {
        return cache;
    }

    @Override
    public Mono<ResponseEntity<ListResponse>> list() {
        return reactiveExecutor.list();
    }

    @Override
    public Mono<ResponseEntity<ListResponse>> list(ListRequest listRequest) {
        return reactiveExecutor.list(listRequest);
    }

    @Override
    public Mono<ResponseEntity<SearchResponse>> search(String fileName) {
        return reactiveExecutor.search(fileName);
    }

    @Override
    public Mono<ResponseEntity<SearchResponse>> search(String fileName, CategoryEnum categoryEnum) {
        return reactiveExecutor.search(fileName, categoryEnum);
    }

    @Override
    public Mono<ResponseEntity<SearchResponse>> search(SearchRequest searchRequest) {
        return reactiveExecutor.search(searchRequest);
    }

    @Override
    public Mono<ResponseEntity<BaseItem>> get(String fileId) {
        return reactiveExecutor.get(fileId);
    }

    @Override
    public Mono<ResponseEntity<DownloadUrlResponse>> getDownloadUrl(String fileId) {
        return reactiveExecutor.getDownloadUrl(fileId);
    }

    @Override
    public Mono<ResponseEntity<Resource>> downloadFile(String fileId, HttpHeaders httpHeaders) {
        return reactiveExecutor.downloadFile(fileId, httpHeaders);
    }

    @Override
    public Mono<ResponseEntity<CreateFolderResponse>> createFolder(String parentFileId, String name, CheckNameEnum checkNameEnum) {
        return reactiveExecutor.createFolder(parentFileId, name, checkNameEnum);
    }

    @Override
    public Mono<ResponseEntity<CreateFolderResponse>> createFolder(String parentFileId, String name) {
        return reactiveExecutor.createFolder(parentFileId, name);
    }

    @Override
    public Mono<ResponseEntity<CreateFolderResponse>> createFolder(String name) {
        return reactiveExecutor.createFolder(name);
    }

    @Override
    public Mono<CreateFileResponse> uploadFile(String parentFileId, Path path, CheckNameEnum checkNameEnum) {
        return reactiveExecutor.uploadFile(parentFileId, path, checkNameEnum);
    }

    @Override
    public Mono<CreateFileResponse> uploadFile(String parentFileId, Path path) {
        return reactiveExecutor.uploadFile(parentFileId, path);
    }

    @Override
    public Mono<CreateFileResponse> uploadFile(Path path) {
        return reactiveExecutor.uploadFile(path);
    }

    @Override
    public Mono<ResponseEntity<Void>> trash(String fileId) {
        return reactiveExecutor.trash(fileId);
    }

    @Override
    public Mono<ResponseEntity<BaseItem>> update(UpdateRequest updateRequest) {
        return reactiveExecutor.update(updateRequest);
    }

    @Override
    public Mono<ResponseEntity<BaseItem>> update(String fileId, String name) {
        return reactiveExecutor.update(fileId, name);
    }
}
